/*
Java board game library.
Copyright (C) 2011  Deepesh Garg

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package d.g.boardgames.chess.player;

import java.awt.Frame;
import java.awt.Window;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JOptionPane;

import d.g.boardgames.Board;
import d.g.boardgames.BoardEventListener;
import d.g.boardgames.Cell;
import d.g.boardgames.chess.ChessBoard;
import d.g.boardgames.chess.ChessBoardRenderProperties;
import d.g.boardgames.chess.ChessMove;
import d.g.boardgames.chess.ChessMoveHelper;
import d.g.boardgames.chess.ChessCellState.PieceType;
import d.g.boardgames.chess.ChessMove.Casteling;


public class GuiListenerMoveSource implements BoardEventListener, MoveSource {

	SourceDelegatePlayer moveSink;
	ChessBoardRenderProperties renderProperties;
	
	PawnPromotionDialog pawnPromotionDialog = null;
	
	boolean enabled = false;
	
	List <Cell> validMoves;
	Cell fromCell;
	
	public GuiListenerMoveSource () {
		Window [] availableWindows = Window.getOwnerlessWindows();
		Frame rootFrame = null;
		for (Window window: availableWindows) {
			if (window instanceof Frame) {
				rootFrame = (Frame) window;
				break;
			}
		}
		if (rootFrame != null) {
			pawnPromotionDialog = new PawnPromotionDialog(rootFrame, true);
		}
	}
	
	@Override
	public void boardAction(Board board, int row, int col) {
		if (!enabled) {
			return;
		}
		ChessBoard chessBoard = (ChessBoard) board;
		if (chessBoard.getTurn() != moveSink.getPlayerColor()) {
			return ;
		}
		Cell cell = new Cell(row, col);
		if (fromCell == null || validMoves == null || validMoves.size() == 0) {
			selectCell (chessBoard, cell);
		} else if (validMoves != null && validMoves.size() > 0) {
			if (validMoves.contains(new Cell(row, col))) {
				attemptMove(chessBoard, cell);
			} else {
				selectCell (chessBoard, cell);
			}
		}
	}
	
	private void selectCell (ChessBoard chessBoard, Cell cell) {
		fromCell = cell;
		validMoves = ChessMoveHelper.getValidMoves(chessBoard, fromCell) ;
		if (renderProperties != null) {
			renderProperties.setValidMoves(validMoves);
			renderProperties.setSelectedCell(fromCell);
		}
	}
	
	private void attemptMove (ChessBoard chessBoard, Cell cell) {
		Cell toCell = cell;
		//ChessMove chessMove = new ChessMove (fromCell, toCell);
		
		ChessMove chessMove = ChessMoveHelper.getChessMove(chessBoard, fromCell, toCell);
		if (chessMove != null && chessMove.getCasteling() == Casteling.NONE &&
			(chessMove.getToCell().getRow() == 0 || chessMove.getToCell().getRow() == 7) &&
			(chessBoard.getCellState(fromCell).pieceType == PieceType.PAWN)) {
			String pawnPromotion = showPawnPromotionDialog();
			if (pawnPromotion.equals("Queen")) {
				chessMove.setPawnPromotion(PieceType.QUEEN);
			}
			if (pawnPromotion.equals("Rook")) {
				chessMove.setPawnPromotion(PieceType.ROOK);
			}
			if (pawnPromotion.equals("Bishop")) {
				chessMove.setPawnPromotion(PieceType.BISHOP);
			}
			if (pawnPromotion.equals("Knight")) {
				chessMove.setPawnPromotion(PieceType.KNIGHT);
			}
		}
		validMoves = null;
		renderProperties.setValidMoves(null);
		renderProperties.setSelectedCell(null);
		fromCell = null;
		moveSink.notifyMove(chessMove);
	}

	public String showPawnPromotionDialog() {
		 JOptionPane pane = new JOptionPane();
	     pane.setOptions(new String[]{"Queen", "Rook", "Bishop", "Knight"}); // Configure
	     pane.setMessage("Promote pawn to");
	     JDialog dialog = pane.createDialog("Pawn promotion");
	     dialog.setVisible(true);
	     return (String)pane.getValue();
	}
	
	public ChessBoardRenderProperties getRenderProperties() {
		return renderProperties;
	}

	public void setRenderProperties(ChessBoardRenderProperties renderProperties) {
		this.renderProperties = renderProperties;
	}
	
	public void registerSink (SourceDelegatePlayer sink) {
		moveSink = sink;
	}
	
	public void startThinking (ChessBoard cb) {
		enabled = true;
	}
	
	public void stopThinking () {
		enabled = false;
		moveSink.notifyMove(null);
	}
	
	class PawnPromotionDialog extends JDialog{ //implements ActionListener {
		public PawnPromotionDialog (Frame parent, boolean model) {
			super (parent, model);
		}
	}
}
